package main

import (
	"fmt"
	"io"
	"net"
	"sync"
	"time"
)

type Server struct {
	Ip   string
	Port int

	// 在线用户列表
	OnlineUserMap map[string]*User
	mapLock       sync.RWMutex

	// 广播消息管道
	Message chan string
}

// 创建一个server接口
func NewServer(ip string, port int) *Server {

	server := &Server{
		Ip:            ip,
		Port:          port,
		OnlineUserMap: make(map[string]*User),
		Message:       make(chan string),
	}

	return server
}

func (server *Server) broadcast(user *User, msg string) {
	sendMsg := "发送广播消息:[" + user.Addr + "]" + user.Name + "：" + msg + "\n"

	server.Message <- sendMsg
}

// 监听服务器全局消息  收到消息就广播发送
func (server *Server) ListenMessage() {
	for {
		globalMsg := <-server.Message

		server.mapLock.Lock()
		for _, userItem := range server.OnlineUserMap {
			userItem.C <- globalMsg
		}
		server.mapLock.Unlock()
	}
}

func (server *Server) Handler(conn net.Conn) {
	// 建立连接之后的操作
	fmt.Println("链接建立成功！")

	user := NewUser(conn, server)

	// 用户上线
	user.Online()

	isAlive := make(chan bool)

	// 监听用户发送的消息
	buffer := make([]byte, 4096)
	go func() {
		size, err := user.Conn.Read(buffer)

		if size == 0 {
			// 代表用户下线
			user.Offline()
			return
		}

		if err != nil && err != io.EOF {
			fmt.Println("从客户端连接读取消息失败：", err)
			return
		}

		msg := string(buffer[:size-1])

		user.handleUserMsg(msg)

		isAlive <- true
	}()

	// 阻塞
	for {
		select {
		case <-isAlive:

		case <-time.After(time.Second * 2):
			// user.C <- "您已被强制下线！\n"
			user.Conn.Write([]byte("您已被强制下线！\n"))
			close(user.C)
			user.Conn.Close()

			return
		}
	}
}

// 启动服务器的接口
func (server *Server) Start() {
	// 创建socket listen
	listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", server.Ip, server.Port))

	if err != nil {
		fmt.Println("listener is error!", err)
		return
	}

	defer listener.Close()

	// 启动全局用户上线广播监听
	go server.ListenMessage()
	for {
		// accept
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("建立连接失败！", err)
			continue
		}
		// do something
		server.Handler(conn)

	}
	// destroy

}
